package nc.bs.plugin;

import lombok.extern.slf4j.Slf4j;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.pub.pa.PreAlertObject;
import nc.bs.pub.taskcenter.BgWorkingContext;
import nc.bs.pub.taskcenter.IBackgroundWorkPlugin;
import nc.itf.bd.defdoc.IDefdocService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.vo.am.common.util.CollectionUtils;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.bd.meta.BatchOperateVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFDateTime;
import ssc.mq.util.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

/**
 * 预算编制明细转自定义档案-业务单元
 * @author Administrator
 *
 */
@Slf4j
public class budgetmakedetailToDdfdocPlugin implements IBackgroundWorkPlugin {
    private BaseDAO baseDAO;

    public BaseDAO getBaseDAO() {
        return baseDAO == null ? new BaseDAO() : baseDAO;
    }

    @Override
    public PreAlertObject executeTask(BgWorkingContext bgWorkingContext) throws BusinessException {
        List<Map<String, Object>> list =  querymake(); // 所有需要同步的信息
        String doclist =  querydefdoc(); // 预算事项档案pk

        // 已存在自定义档案信息
        List<DefdocVO> defdocVOList = (List<DefdocVO>)getBaseDAO().retrieveByClause(DefdocVO.class, "pk_defdoclist='"+doclist+"'");
        // 步骤 2: 初始化三个列表来存储分类后的对象
        List<DefdocVO> addlist = new ArrayList<>();
        List<DefdocVO> updlist = new ArrayList<>();
        List<DefdocVO> delList = new ArrayList<>();
        //根据pk匹配
        Map<String, DefdocVO> defdocVOMap = new HashMap<>(); // 已同步的自定义档案信息
        Map<String, DefdocVO> ybusinessMap = new HashMap<>(); // 已同步的自定义档案信息
        for (DefdocVO vo : defdocVOList) {
            String pk = vo.getDef6();
            defdocVOMap.put(pk, vo);
            ybusinessMap.put(pk, vo);
        }

        // 步骤 3: 遍历列表，根据条件分类
        for (Map<String, Object> doc : list) { // 所有需要同步的信息
            String def6 = (String) doc.get("def6");
            DefdocVO vo = defdocVOMap.get(def6);
            if (vo == null) {
                DefdocVO addvo =  new DefdocVO();
                Object pk_org = doc.getOrDefault("pk_org", "0001A210000000003BSQ");
                addvo.setAttributeValue("pk_org",pk_org);
                addvo.setPk_group("0001A210000000000JB9");
                addvo.setPk_defdoclist(doclist);
                addvo.setStatus(VOStatus.NEW);
                addvo.setEnablestate(2);
                addvo.setCreationtime(new UFDateTime());
                addvo.setTs(new UFDateTime());
                addvo.setAttributeValue("code",  doc.getOrDefault("code", ""));
                addvo.setAttributeValue("name",  doc.getOrDefault("name", ""));
                addvo.setAttributeValue("mname",  doc.getOrDefault("mname", ""));
                addvo.setAttributeValue("deptname",  doc.getOrDefault("deptname", ""));
                addvo.setAttributeValue("def1",  doc.getOrDefault("def1", ""));
                addvo.setAttributeValue("def2",  doc.getOrDefault("def2", ""));
                addvo.setAttributeValue("def3",  doc.getOrDefault("def3", ""));
                addvo.setAttributeValue("def4",   doc.getOrDefault("def4", "0")+"");
                addvo.setAttributeValue("def5",  doc.getOrDefault("def5", "0")+"");
                addvo.setAttributeValue("def6", doc.getOrDefault("def6", ""));
                addvo.setAttributeValue("def7", doc.getOrDefault("def7", ""));
                addvo.setAttributeValue("dr",0);
                // 未匹配到，创建新的 DefdocVO 并添加到新增列表
                addlist.add(addvo); // 注意：这里 dr 为 null，因为是从新数据中来的
            } else {
                vo.setStatus(VOStatus.UPDATED);
                Object year = doc.getOrDefault("def7", LocalDate.now().getYear());
                int currentYear = LocalDate.now().getYear();
                if (currentYear != Integer.parseInt(year.toString())){ // 不是当前年份，则停用
                    vo.setEnablestate(3);
                }else{
                    if(doc.getOrDefault("dr", 0) == Integer.valueOf(1)){ // 说明预算编制中已经删除
                        vo.setEnablestate(3);
                    }
                    vo.setEnablestate(2);
                }
                // 匹配到且 dr!=1，添加到更新列表
                vo.setAttributeValue("code",  doc.getOrDefault("code", ""));
                vo.setAttributeValue("name",  doc.getOrDefault("name", ""));
//                vo.setAttributeValue("mname",  doc.getOrDefault("mname", ""));
//                vo.setAttributeValue("deptname",  doc.getOrDefault("deptname", ""));
//                vo.setAttributeValue("def1",  doc.getOrDefault("def1", ""));
//                vo.setAttributeValue("def2",  doc.getOrDefault("def2", ""));
//                vo.setAttributeValue("def3",  doc.getOrDefault("def3", ""));
                Object o = doc.get("def4");
                vo.setAttributeValue("def4",   o+"");
//                vo.setAttributeValue("def5",  doc.getOrDefault("def5", "0")+"");
//                vo.setAttributeValue("def6",  doc.getOrDefault("def6", "0")+"");
//                vo.setAttributeValue("def7", doc.getOrDefault("def7", ""));
                vo.setAttributeValue("dr",0);
                vo.setModifiedtime(new UFDateTime());
//                updlist.add(vo);
                ybusinessMap.put(def6, vo);
            }

        }
        // 注意：这里我们没有处理剩余未匹配的 DefdocVO，因为在我们的逻辑中，未匹配的都视为新增，并且已经在上面处理了

        // 步骤 4: 将列表转换为数组
        DefdocVO[] addArray = addlist.toArray(new DefdocVO[0]);
        for (String key : ybusinessMap.keySet()) {
            updlist.add(ybusinessMap.get(key));
        }
        DefdocVO[] updArray = updlist.toArray(new DefdocVO[0]);
        DefdocVO[] delArray = delList.toArray(new DefdocVO[0]);

        // 步骤 5: 设置 batchVO 的属性
        BatchOperateVO batchVO = new BatchOperateVO();
        batchVO.setDelObjs(delArray);
        batchVO.setAddObjs(addArray);
        batchVO.setUpdObjs(updArray);
        try{
            BatchOperateVO savedBatchVO = ((IDefdocService) NCLocator.getInstance() .lookup(IDefdocService.class)).batchSaveDefdoc("0001A210000000003BSQ",batchVO);
            this.getBaseDAO().executeUpdate("commit;");
        }catch (BusinessException e){
            Logger.error("错误信息:"+e.getMessage());
        }
        return null;
    }

    public List<Map<String, Object>> querymake() throws BusinessException {
        String sql =  " SELECT\n" +
                "   detail.dr, make.nyear def7,\n" +
                "   CONCAT(detail.budgetno, SUBSTR(detail.pk_budgetmakedetail, 16))  AS code,  \n" +
                "   ( CASE WHEN ject.project_name IS NOT NULL THEN ject.project_name || '/' ELSE '' END ) || (\n" +
                " CASE WHEN ject1.project_name IS NOT NULL \n" +
                "     AND ( ject.project_name IS NOT NULL OR ject2.project_name IS NULL ) THEN\n" +
                "      ject1.project_name || '/' ELSE '' \n" +
                "     END  ) || ( CASE WHEN bd_fundsource.name IS NOT NULL THEN bd_fundsource.name || '/' ELSE '' END )  \n" +
                "     || ( CASE WHEN class.name IS NOT NULL THEN class.name || '/' ELSE '' END )  \n" +
                "     || ( CASE WHEN dept.name IS NOT NULL THEN dept.name || '/' ELSE '' END )  \n" +
                "     || ( CASE WHEN detail.budgetno IS NOT NULL THEN CONCAT(detail.budgetno , SUBSTR(detail.pk_budgetmakedetail, 16))  ELSE detail.pk_budgetmakedetail END ) AS name,\n" +
                "     ject.project_name AS mname, bd_fundsource.name AS deptname,\n" +
                "     detail.pk_org AS pk_org,\n" +
                "     detail.pk_project AS def1, detail.pk_inoutclass AS def2,\n" +
                "     detail.pk_fundsource AS def3, detail.amount AS def4,\n" +
                "     detail.pk_budgetmakedetail AS def6 ,+ make.pk_budgetdept AS def5,+ ROW_NUMBER ( ) OVER ( PARTITION BY detail.budgetno ORDER BY detail.pk_project ) AS rn \n" +
                "   FROM\n" +
                "     hrpbm_budgetmakedetail detail\n" +
                "     LEFT JOIN bd_project ject ON ject.pk_project = detail.pk_project\n" +
                "     LEFT JOIN bd_project ject1 ON ject1.pk_project = ject.pk_parentpro\n" +
                "     LEFT JOIN bd_project ject2 ON ject2.pk_project = ject1.pk_parentpro\n" +
                "     LEFT JOIN bd_inoutbusiclass class ON detail.pk_inoutclass = class.pk_inoutbusiclass\n" +
                "     LEFT JOIN bd_fundsource ON detail.pk_fundsource = bd_fundsource.pk_fundsource \n" +
                "     LEFT JOIN hrpbm_budgetmake make ON make.pk_budgetmake = detail.pk_budgetmake \n" +
                "     LEFT JOIN hrpbm_budgetdept dept ON make.pk_budgetdept = dept.pk_budgetdept \n" +
                "   WHERE 1 = 1\n" +
                "      and detail.pk_project != '~'  \n" +
                "      and make.taskstate = '99'\n" +
                "      ORDER BY detail.budgetno asc  ";

        List<Map<String, Object>> sqlResult =
                (List<Map<String, Object>>) this.getBaseDAO().executeQuery(sql.toString(),
                        new MapListProcessor());
        if (CollectionUtils.isEmpty(sqlResult)) {
            return null;
        }

        return sqlResult;
    }


    public String querydefdoc() throws BusinessException {
        String sql="select pk_defdoclist from bd_defdoclist list where list.code='yusuanxx'";

        String sqlResult = (String) this.getBaseDAO().executeQuery(sql.toString(),
                new ColumnProcessor());
        if (sqlResult.isEmpty()) {
            return null;
        }

        return sqlResult;
    }
}